﻿
using DataService.Common;
using DataService.Core.Common;
using DataService.Core.ServiceDTO;
using DataService.Core.ServiceDTO.Const;
using DataService.DataAccessLayer.Provider;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data.Common;
using System.IO;
using System.Text;
using System.Threading;
using static Mysqlx.Crud.Find.Types;

namespace DataService.DataAccessLayer
{
    public class SQLiteProvider : DatabaseProvider
    {




        public override DatabaseType DBType => DatabaseType.SQLite;
        public override Type DatabaseProviderType => typeof(SQLiteProvider);
        private static DbProviderFactory _SqliteFactory;

        public override DbProviderFactory ProviderFactory
        {
            get
            {
                if (_SqliteFactory == null)
                {
                    lock (typeof(SQLiteProvider))
                    {
                        string dir = FilePathHelper.BasePath + "System.Data.SQLite.dll";
                        _SqliteFactory = GetProviderFactory(dir, "System.Data.SQLite.SQLiteFactory");
                      //  System.Console.WriteLine("实例化sqlite驱动工厂");
                        if (_SqliteFactory == null)
                        {
                            _SqliteFactory = GetProviderFactory("Microsoft.Data.Sqlite.dll", "Microsoft.Data.Sqlite.SqliteFactory");
                        }
                    }
                }
                // 设置线程安全模式
                //if (_Factory != null) SetThreadSafe();
                return _SqliteFactory;
            }
        }
        //private void SetThreadSafe()
        //{ 
        //}





        //        读写锁
        // SQLite锁的级别依次是：NoLock Shared Reserved Pending Exclusive。

        //Shared是一般意义上的读锁，允许同时有多个并发读
        //Exclusive是一般意义上的写锁，只允许有一个，作用于整个数据库文件，不允许其它连接读，只有自己能读写
        //Reserved是写日志阶段时的锁，也只允许有一个。关键是此时仍能加读锁，只是不能再加Reserved或更高级别的锁
        //Pending是Commit时发生的，会阻止加新的读锁，等所有已有读锁都释放了就进入Exclusive
        //对于一个事务，刚开始Select的时候只有Shared锁，等开始DML了就会加Reserved锁，Commit时进入Pending阶段，如果一段时间内没等到所有的读锁都释放，锁就升级失败。

        //        隔离级别
        //隔离级别默认情况下是最高的Serializable。

        //脏读：

        //事务T1将某一值修改，然后事务T2读取该值，此后T1因为某种原因撤销对该值的修改，这就导致了T2所读取到的数据是无效的。
        //T1修改了没提交，T2读不到T1的内容，因为T1只往日志里写了东西，T2是直接读的文件。因此不会出现脏读。

        //不可重复读：

        //事务T1读取某一数据，事务T2读取并修改了该数据，T1为了对读取值进行检验而再次读取该数据，便得到了不同的结果。
        //T1和T2都能读取，此时T1存在读锁，T2可以修改但无法提交，此情形同脏读。因此不会出现不可重复读。

        //幻读：

        //第一个事务对一个表中的数据进行了修改，比如这种修改涉及到表中的“全部数据行”。同时，第二个事务也修改这个表中的数据，这种修改是向表中插入“一行新数据”。那么，以后就会发生操作第一个事务的用户发现表中还存在没有修改的数据行。
        //T1修改了没提交，存在写锁，T2无法修改；或者T1一开始读取了，存在读锁，T2能修改但无法提交。总之此时无法修改数据库，因此不会出现幻读。


    }
}
